﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include <initializer_list>

//在C++98中，标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。
//struct Point
//{
//	int x;
//	int y;
//};
//
//int main()
//{
//	int x1 = 1;
//	int x2{ 2 };
//
//	int arr1[]{ 1,2,3,4,5 };
//	int arr2[5]{ 1 };
//
//	Point p{ 1,2 };
//
//	//甚至列表初始化也能运用到new表达式中
//	int* pa = new int[4] {0};
//	return 0;
//}

//int main()
//{
//	int arr[] = { 1,2,3,4,5 };
//	int arr2[5] = { 1 };
//	Point p = { 1,2 };
//	return 0;
//}


//void foo(std::initializer_list<int> values)
//{
//    for (auto value : values)
//    {
//        std::cout << value << " ";
//    }
//}
//
//
//int main()
//{
//    foo({ 1,2,3,4,5 });
//    return 0;
//}
#include<map>
#include<string>
#include<vector>
#include<assert.h>
////int main()
////{
////	map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
////	auto it = dict.begin();
////	vector<decltype(it)>arr;
////	return 0;
////}

//int main()
//{
//	// 左值引用只能引用左值，不能引用右值。
//	int a = 10;
//	int& ra1 = a;   // ra为a的别名
//	//int& ra2 = 10;   // 编译失败，因为10是右值
//	// const左值引用既可引用左值，也可引用右值。
//	const int& ra3 = 10;
//	const int& ra4 = a;
//	return 0;
//}


//int main()
//{
//	int&& r1 = 10;
//
//	int a = 10;
//	int&& r2 = a;//会报错，无法将左值绑定到右值引用
//
//	// 右值引用可以引用move以后的左值
//	int&& r3 = move(a);
//
//	return 0;
//}
namespace test
{
	class string
	{
	public:

		typedef char* iterator;
		iterator begin()
		{
			return str;
		}
		iterator end()
		{
			return str + size;
		}

		string(const char* s = "")//默认构造
			:size(strlen(s))
			, capacity(size)
		{
			str = new char[capacity + 1];
			strcpy(str, s);
		}
		void swap(string& s)
		{
			std::swap(str, s.str);
			std::swap(size, s.size);
			std::swap(capacity, s.capacity);
		}

		string(const string& s)//拷贝构造
			:str(nullptr)
		{
			cout << "拷贝构造" << endl;
			string tmp(s.str);
			swap(tmp);
		}

		string& operator=(const string& s)
		{
			cout << "赋值重载" << endl;
			string tmp(s);
			swap(tmp);
		}

		string(string&& s)
			:str(nullptr)
			, size(0)
			, capacity(0)
		{
			cout << "移动构造" << endl;
			swap(s);
		}

		string& operator=(string&& s)
		{
			cout << "移动赋值" << endl;
			swap(s);
			return *this;
		}

		~string()
		{

			delete[]str;
			str = nullptr;
		}

		char& operator[](size_t pos)
		{
			assert(pos < size);
			return str[pos];
		}
		void reserve(size_t n)
		{
			if (n > capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, str);
				delete[] str;
				str = tmp;
				capacity = n;
			}
		}

		void push_back(char ch)
		{
			if (size >= capacity)
			{
				size_t newcapacity = capacity == 0 ? 4 : capacity * 2;
				reserve(newcapacity);
			}
			str[size] = ch;
			++size;
			str[size] = '\0';
		}


		//string operator+=(char ch)
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}

		const char* c_str() const
		{
			return str;
		}

	private:
		char* str;
		size_t size;
		size_t capacity;//不包含最后做标识的\0
	};
}

void func1(test::string s)
{

}

void func2(const test::string& s)
{

}

int main()
{
	test::string s1("hello world");

	// func1和func2的调用我们可以看到左值引用做参数减少了拷贝，提高效率的使用场景和价值
	func1(s1);
	func2(s1);

	// string operator+=(char ch) 传值返回存在深拷贝
	// string& operator+=(char ch) 传左值引用没有拷贝提高了效率
	s1 += '!';
	return 0;
}

struct Goods
{
	string _name;//名字
	double _price; // 价格
	int _evaluate; // 评价
	Goods(const char* str, double price, int evaluate)
		:_name(str)
		, _price(price)
		, _evaluate(evaluate)
	{}
};